import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:fnos_tv_desktop/core/api/bean/get_media_list_body.dart';
import 'package:fnos_tv_desktop/core/api/bean/login_result.dart';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:fnos_tv_desktop/core/api/bean/media_db_result.dart';
import 'package:fnos_tv_desktop/core/api/bean/media_info_result.dart';
import 'package:fnos_tv_desktop/core/api/bean/media_list_result.dart';
import 'package:fnos_tv_desktop/core/api/bean/user_info_result.dart';
import 'package:fnos_tv_desktop/core/api/interceptor/no_login_interceptor.dart';
import 'package:path/path.dart';
import '../core.dart';
import 'interceptor/login_interceptor.dart';

class Api {
  static Api? _api;

  static void logout() {
    _api?.loginDio.close(force: true);
    _api = null;
  }

  factory Api([String? host]) {
    if (host != null) {
      _api = Api._(host);
    }
    return _api!;
  }

  final String host;
  late final cookieJar = PersistCookieJar(
    storage: FileStorage(join(Core.document.absolute.path, '.cookies', '')),
  );
  late final cookieManager = CookieManager(cookieJar);
  final logInterceptor = LogInterceptor(responseBody: true, requestBody: true);

  late final Dio loginDio = Dio(BaseOptions(baseUrl: '$host/v'))
    ..interceptors.addAll([
      cookieManager,
      LoginInterceptor(this),
      if (kDebugMode) logInterceptor,
    ]);

  late final Dio noLoginDio = Dio(BaseOptions(baseUrl: '$host/v'))
    ..interceptors.addAll([
      cookieManager,
      NoLoginInterceptor(),
      if (kDebugMode) logInterceptor,
    ]);

  String? token;

  Api._(this.host);

  String imageUrl(String path) {
    return '$host/v/api/v1/sys/img$path';
  }

  Future<String?> loginWithPassword(String username, String password) async {
    final api = '/api/v1/login';
    try {
      final response = await noLoginDio.post(
        api,
        data: {
          'username': username,
          'password': password,
          'app_name': 'trimemedia-web',
        },
      );
      final result = LoginResult.fromJson(response.data);
      token = result.token;
      return null;
    } catch (e) {
      return e.toString();
    }
  }

  Future<UserInfoResult> getUserInfo() async {
    final api = '/api/v1/user/info';
    final response = await loginDio.get(api);
    final result = UserInfoResult.fromJson(response.data);
    return result;
  }

  Future<List<MediaDbResult>> getMediaDatabases() async {
    final api = '/api/v1/mediadb/list';
    final response = await loginDio.get(api);
    final results = (response.data as List)
        .map((e) => MediaDbResult.fromJson(e))
        .toList();
    return results;
  }

  Future<Map<String, dynamic>> getMediaDbSum() async {
    final api = '/api/v1/mediadb/sum';
    final response = await loginDio.get(api);
    return response.data;
  }

  Future<List<MediaInfoResult>> getPlayList() async {
    final api = '/api/v1/play/list';
    final response = await loginDio.get(api);
    final results = (response.data as List).map((e) {
      return MediaInfoResult.fromJson(e);
    }).toList();
    return results;
  }

  Future<MediaListResult> getMediaList(GetMediaListBody body) async {
    final api = '/api/v1/item/list';
    final response = await loginDio.post(api, data: body.toJson());
    final result = MediaListResult.fromJson(response.data);
    return result;
  }
}
